﻿using System;
// .NET框架为事件定义了一个标准模式。它的目的是保持框架和用户代码之间的一致性。
// 标准事件的核心是System.EventArgs——预定义的没有成员的框架类（不同于静态Empty属性）。
// EventArgs是用于为事件传递信息的基类。

namespace _093_标准事件模式
{
    //我们定义EventArgs的子类，用来在事件PriceChanged被引发时，传递新旧Price值
    public class PriceChangedEventArgs:System.EventArgs
    {
        public readonly decimal LastPrice;
        public readonly decimal NewPrice;
        public PriceChangedEventArgs(decimal lastPrice,decimal newPrice)
        {
            LastPrice = lastPrice;
            NewPrice = newPrice;
        }
    }
    //考虑到复用性，EventArgs类自根据它包含的内容命名（而非根据被使用的事件命名）。它一般以属性或只读字段将数据。
    // 定义了EventArgs的子类，下一步时选择或定义事件的委托，需遵循三条原则：
    //    委托必须以void作为返回值。
    //    委托必须接受两个参数：第一个是object类，第二个是EventArgs的子类。第一个参数表明事件的广播者，第二个是包含需要传递的额外信息。
    //    委托的名称必须以EventHandler结尾。
    
    // 框架定义一个名为System.EventHandler<>的泛化委托，该委托满足如下条件：
    //public delegate void EventHandler<TEventArgs>(object sender, PriceChangedEventArgs e);)
    
    //在下一步是定义选定委托类型的事件，这里使用泛化委托EventHandler：
    public class Stock
    {
        public event EventHandler<PriceChangedEventArgs> PriceChanged;
        //最后，该模式要求写一个受保护的（protected）虚方法引发事件。方法名必须和事件名一致，以On作为前缀，并接受唯一的EventArgs参数：
        protected virtual void OnPriceChanged(PriceChangedEventArgs e)
        {
            if (PriceChanged != null) PriceChanged(this, e);
            //提示：在多线程情形下，为了保证线程安全，在测试和调用委托前，需要将它指定到一个临时变量上：
            //var temp = PriceChanged;
            //if(temp != null) temp(this, e);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}
